package com.example.helloandroid;

import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;

import lib.IniProperties;
import lib.MapParser;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

public class Game extends View {

	private static final int FRAME_DELAY = 40; // 20ms. implies 50fps (1000/20)
												// = 50
	long cycleTime;
	boolean canSend = true;
	short x = 0;
	short y = 0;
	int layer = 0;
	Game g;
	boolean start = false;
	String server = "10.0.2.2";
	DatagramPacket packet;
	InetAddress address;
	DatagramSocket socket;
	public int twidth;
	public int theight;

	int id;
	ByteBuffer received;
	Bitmap img;
	Bitmap[] tile = new Bitmap[10];
	int count = 8;
	public byte[][][] tileMap = new byte[16][100][100];

	public Game(Context context) {
		super(context);

		Resources res = getContext().getResources();
		tileMap[0] = MapParser.getMap(res, (byte) 0, (byte) 0, (byte) 1);
		try {

			InputStream is = res.getAssets().open("server.ini");
			IniProperties.getInstance().load(is);
			twidth = Integer.parseInt(IniProperties.getInstance().getProperty(
					"MapSettings", "TileWidth"));
			Log.d("UDP", "S: TileW: " + twidth);
			theight = Integer.parseInt(IniProperties.getInstance().getProperty(
					"MapSettings", "TileHeight"));
			img = BitmapFactory.decodeResource(getResources(),
					R.drawable.edgepic);
			// System.out.println(twidth);
			Bitmap limg = BitmapFactory.decodeResource(getResources(),
					R.drawable.tileset);
			int total = (limg.getHeight() / theight)
					* (limg.getWidth() / twidth);

			tile = new Bitmap[total];

			int counter = 0;
			for (int k = 0; k < (limg.getHeight() / theight); k++) {
				for (int j = 0; j < (limg.getWidth() / twidth); j++) {
					tile[counter] = Bitmap.createBitmap(limg, j * twidth, k
							* theight, twidth, theight);
					counter++;

				}
			}
			// System.out.println("countersss "+counter);
		} catch (Exception ex) {
			ex.printStackTrace();
			// Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null,
			// ex);
		}
		// System.out.println("hey");
		String name = "admin";
		String pass = "admin";
		// send request
		byte[] buf = new byte[256];
		buf[0] = 0;
		buf[1] = (byte) name.length();
		int k = 2;
		for (int i = 0; i < name.length(); i++) {
			buf[k] = name.getBytes()[i];
			k++;
		}
		buf[k] = (byte) pass.length();
		k++;
		for (int j = 0; j < pass.length(); j++) {
			buf[k] = pass.getBytes()[j];
			k++;
		}
		try {
			Log.d("UDP", "S: Connecting...");
			socket = new DatagramSocket();
			address = InetAddress.getByName(server);
			Log.d("UDP", "S: Connected");

			packet = new DatagramPacket(buf, buf.length, address, 4445);
			socket.send(packet);
			Log.d("UDP", "S: Enviou");
			// get response
			packet = new DatagramPacket(buf, buf.length);
			socket.receive(packet);
			Log.d("UDP", "S: Recebeu");
			ByteBuffer r = ByteBuffer.allocate(1000);
			r.put(packet.getData());
			r.rewind();
			// byte[] serverResponse=packet.getData();
			if (r.get() == 0) {

			} else {
				start = true;
				Log.d("UDP", "S: Yes");
				id = r.getInt();
			}
		} catch (IOException ex) {
			// Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null,
			// ex);
		}
		this.requestFocus();
		this.setFocusableInTouchMode(true);


	}
	/*
	public void run() {
		Log.d("UDP", "S: Thread iniciada");


		cycleTime = System.currentTimeMillis();

		while (true) {

			try {
				update();
				// updateGUI(strategy);
				synchFramerate();

			} catch (Exception ex) {
			}
		}

	}
	*/
	public void updateAI() throws IOException {
		count++;
		if (start && count >= 8) {
			count = 0;
			canSend = true;
			received = ByteBuffer.allocate(5);

			received.put((byte) 1);
			received.putInt(id);
			
			address = InetAddress.getByName(server);
			packet = new DatagramPacket(received.array(),
					received.array().length, address, 4445);
			socket.send(packet);
			
			// get response
			received = ByteBuffer.allocate(1000);
			packet = new DatagramPacket(received.array(),
					received.array().length);
			socket.receive(packet);
			
			received.put(packet.getData());
			received.rewind();
			if (packet.getData().length >= 5) {
				layer = received.get();
				x = received.getShort();
				y = received.getShort();
			}

		}

	}
	/*
	private void synchFramerate() {
		cycleTime = cycleTime + FRAME_DELAY;
		long difference = cycleTime - System.currentTimeMillis();
		try {
			Thread.sleep(Math.max(0, difference));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	 */
	
	@Override
	protected void onDraw(Canvas canvas) {
		try {
			updateAI();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
		if (start) {
			for (int h = 0; h < tileMap[layer][0].length; h++) {
				for (int j = 0; j < tileMap[layer].length; j++) {
					canvas.drawBitmap(tile[tileMap[layer][j][h]], h * theight,
							j * twidth, null);

				}
			}
			// g.setColor(Color.white);
			// g.fillRect(0, 0, this.getSize().width, this.getSize().height);

			// graphics.setColor(Color.red);
			// graphics.drawString(jTextField1.getText(), x*twidth, y*theight);
			canvas.drawBitmap(img, x * twidth, y * theight, null);
			received.position(5);

			int total = received.getShort();

			for (int k = 0; k < total; k++) {

				int pid = received.getInt();
				byte pLayer = received.get();
				short px = received.getShort();
				short py = received.getShort();
				byte dir = received.get();
				byte voc = received.get();
				short hp = received.getShort();
				short lvl = received.getShort();
				// short mp=received.getShort();

				if (pLayer == layer && pid != id) {
					// graphics.drawString(""+pid, px*twidth, py*theight);
					canvas.drawBitmap(img, px * twidth, py * theight, null);
				}
			}

			invalidate();

		}

		// canvas.drawColor(Color.CYAN);
		// Resources r = this.getContext().getResources();
		//
		// y++;
		// if (y == 100) {
		// y = 0;
		// x++;
		//
		// }
		// Bitmap bd = BitmapFactory.decodeResource(getResources(),
		// R.drawable.tileset);
		// canvas.drawBitmap(bd, x, y, null);
		// // canvas.drawText("hey", 0, 400, null);
		// invalidate();
	}

	/*
	 * handles key events in the game. Update the direction our snake is
	 * traveling based on the DPAD. Ignore events that would cause the snake to
	 * immediately turn back on itself.
	 * 
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onKeyDown(int, android.os.KeyEvent)
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent msg) {
		Log.d("UDP", "S: KeyCode "+keyCode);
		// send request
		ByteBuffer buf = ByteBuffer.allocate(6);
		buf.put((byte) 1);
		buf.putInt(id);
		boolean enviar = false;

		switch (keyCode) {
		case KeyEvent.KEYCODE_DPAD_UP:
			buf.put((byte) 1);
			enviar = true;
			break;
		case KeyEvent.KEYCODE_DPAD_RIGHT:
			buf.put((byte) 2);
			enviar = true;
			break;
		case KeyEvent.KEYCODE_DPAD_DOWN:
			buf.put((byte) 3);
			enviar = true;
			break;
		case KeyEvent.KEYCODE_DPAD_LEFT:
			buf.put((byte) 4);
			enviar = true;
			break;
		case KeyEvent.KEYCODE_A:
			buf = ByteBuffer.allocate(5);
			buf.put((byte) 3);
			buf.putInt(id);
			enviar = true;
			break;
		default:
			buf.put((byte) 0);
			break;

		}
		if (enviar) {
			Log.d("UDP", "S: T2");
			try {
				packet = new DatagramPacket(buf.array(), buf.array().length,
						address, 4445);
				socket.send(packet);
				buf = ByteBuffer.allocate(1000);
				// get response
				packet = new DatagramPacket(buf.array(), buf.array().length);
				socket.receive(packet);
				return true;
			} catch (IOException ex) {

			}
		}

		
		return super.onKeyDown(keyCode, msg);

	}

}
